<template>
  <section class="pagemaker">
    <section class="pagemaker-list">
      <div class="pagemaker-list-header">组件列表</div>
      <div class="pagemaker-list-body">
        <v-list
          :list="list"
          @search="
            (name) => {
              getListData(name)
            }
          "
        />
      </div>
    </section>
    <section class="pagemaker-editor">
      <div class="pagemaker-editor-header">
        <div class="pagemaker-editor-header-title">页面设计</div>
        <div class="pagemaker-editor-header-action">
          <div class="item" @click="save(true)">
            <span class="icon">
              <icon name="staging-icon" />
            </span>
            <span class="txt">返回</span>
          </div>
          <div class="item" @click="view()">
            <span class="icon">
              <icon name="preview-icon" />
            </span>
            <span class="txt">预览</span>
          </div>
          <div class="item" @click="clear()">
            <span class="icon">
              <icon name="clear-icon" />
            </span>
            <span class="txt">清空</span>
          </div>

          <div class="item" @click="save()">
            <span class="icon">
              <icon name="save-icon" />
            </span>
            <span class="txt">保存</span>
          </div>
        </div>
      </div>
      <div class="pagemaker-editor-body">
        <section class="pagemaker-editor-body-banner">
          <div />
        </section>

        <v-editor />

        <section
          class="pagemaker-editor-body-footer"
          :class="{ enter: enter }"
          @drop.stop="drop"
          @dragenter.prevent
          @dragover.prevent="dragOver"
          @dragleave="dragLeave"
          @click="addLayout"
        >
          <icon name="add-icon" />
        </section>
      </div>
    </section>
    <section class="pagemaker-form">
      <el-tabs v-model="active">
        <el-tab-pane
          v-for="(item, index) in tabs"
          :key="index"
          :name="item.value"
        >
          <span slot="label">{{ item.label }}</span>
        </el-tab-pane>
      </el-tabs>

      <section v-show="active == 'page'">
        <div class="pagemaker-form-body">
          <v-form-page />
        </div>
      </section>
      <section v-show="active == 'widget'">
        <div class="pagemaker-form-body">
          <v-form-widget />
        </div>
      </section>
      <section v-show="active == 'compVariate'">
        <div class="pagemaker-form-body">
          <v-comp-var />
        </div>
      </section>
      <section v-show="active == 'pageVariate'">
        <div class="pagemaker-form-body">
          <v-page-var />
        </div>
      </section>
    </section>
    <el-dialog
      :close-on-click-modal="false"
      :visible.sync="visible"
      title="设置初始值"
      center
      :before-close="
        () => {
          visible = false
        }
      "
    >
      <el-form ref="form" :model="varForm" label-width="140px">
        <el-form-item
          v-for="(item, index) in varList"
          :key="item + index"
          :label="varList[index].name"
        >
          <el-input v-model="varForm[item.code]" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button
          style="padding: 8px 30px"
          @click="visible = false"
        >关 闭</el-button>
        <el-button
          type="primary"
          style="padding: 8px 30px"
          @click="handleVarSubmit"
        >确 定</el-button>
      </div>
    </el-dialog>
  </section>
</template>
<script>
import VList from './list'
import VFormWidget from './form/widget'
import VFormPage from './form/page'
import VPageVar from './form/pageVar'
import VCompVar from './form/compVar'
import VEditor from './editor'
import VRelate from './relate'
import { Extend } from '@/components/CustomPage/fields/widget'
import { deepClone, randomStringForId } from '@/utils'
import FieldMap from '@/components/CustomPage/apps/map'
import { query, save, publish, getPort, getLabel } from './api'
import { queryComponents, queryThemeColor } from '@/components/CustomPage/api'

export default {
  name: 'FormMaker',
  componentname: 'FormMaker',
  components: { VList, VFormWidget, VFormPage, VEditor, VPageVar, VCompVar },
  props: {
    pageId: {
      type: String,
      default: ''
    },
    ctType: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      comps: [{ type: 'layout', id: '1', components: [] }],
      pageconfig: {},
      headerconfig: {},
      footerconfig: {},
      dragState: null,
      focusId: null,
      focusName: '',
      portList: [],
      labelClass: [],
      focusForm: [],
      pageVar: [],
      compVar: [],
      relation: {},
      name_: '',
      icon_: 'table',
      desc_: '',
      key: 0,
      ctId: '',
      enter: false,
      tabs: [
        {
          label: '组件设置',
          value: 'widget'
        },
        {
          label: '组件变量',
          value: 'compVariate'
        },
        {
          label: '页面设置',
          value: 'page'
        },
        {
          label: '页面变量',
          value: 'pageVariate'
        }
      ],
      active: 'widget',
      ZDYYMBL: [],
      varList: [],
      visible: false,
      varForm: {},
      list: []
    }
  },
  provide() {
    return {
      comps: () => this.comps,
      pageconfig: () => this.pageconfig,
      headerconfig: () => this.headerconfig,
      headerHeight: () => {
        return this.px2rem(this.headerconfig.height || 0)
      },
      footerconfig: () => this.footerconfig,
      footerHeight: () => {
        return this.px2rem(this.footerconfig.height || 0)
      },
      dragState: () => this.dragState,
      focusId: () => this.focusId,
      focusForm: () => this.focusForm,
      pageVar: () => this.pageVar,
      compVar: () => this.compVar,
      compList: () => this.list,
      getPortListFun: (id) => {
        return this.getPortListFun(id)
      },
      getListItemInfo: (code) => {
        return this.getListItemInfo(code)
      },
      getCompObj: (id) => {
        return this.getCompObj(id)
      },
      focusName: () => this.focusName,
      portList: () => this.portList,
      labelClass: () => this.labelClass
    }
  },
  created() {
    const { ctType } = this
    this.init()
  },
  beforeDestroy() {
    // document.documentElement.style.fontSize = ''
  },
  methods: {
    async init() {
      await this.getListData()
      await this.getThemeColor()
      if (this.ctType !== '') {
        this.getDatas()
      } else {
        this.getData()
      }
      document.documentElement.style.fontSize = (375 * 75) / 750 + 'px'
      this.on_event('drag-start', (e) => {
        const { data } = e
        this.dragState = data
        e.stopPropagation()
      })
      this.on_event('toggle', (e) => {
        const { data } = e
        this.toggle(data)
        e.stopPropagation()
      })
      this.on_event('move-vertical', (e) => {
        const { data } = e
        this.dragState.moveTop = data
        e.stopPropagation()
      })
      this.on_event('move-horizion', (e) => {
        const { data } = e
        this.dragState.moveLeft = data
        e.stopPropagation()
      })
      this.on_event('add-wapper', (e) => {
        const { data } = e
        this.addWapper(data)
        e.stopPropagation()
      })
      this.on_event('focus-wapper', (e) => {
        const { data } = e
        this.focusWapper(data)
        e.stopPropagation()
      })
      this.on_event('focus-header', (e) => {
        const { data } = e
        this.focusHeader(data)
        e.stopPropagation()
      })
      this.on_event('focus-footer', (e) => {
        const { data } = e
        this.focusFooter(data)
        e.stopPropagation()
      })
      this.on_event('remove-wapper', (e) => {
        const { data } = e
        this.removeWapper(data)
        e.stopPropagation()
      })
      this.on_event('add-layout', (e) => {
        this.addLayout()
        e.stopPropagation()
      })
      this.on_event('remove-layout', (e) => {
        const { data } = e
        this.removeLayout(data)
        e.stopPropagation()
      })
      this.on_event('widget-form-change', (e) => {
        const { data } = e
        this.widgetformchange(data)
        e.stopPropagation()
      })
      this.on_event('page-form-change', (e) => {
        const { data } = e
        this.pageformchange(data)
        e.stopPropagation()
      })
      this.on_event('page-pageVar-change', (e) => {
        const { data } = e
        this.pageVar = data
        e.stopPropagation()
      })
      this.on_event('page-compVar-change', (e) => {
        const { data } = e
        this.setCompVar(data)
        e.stopPropagation()
      })
    },

    getThemeColor() {
      let defaultColor = '#eb523c'
      return new Promise((resolve, reject) => {
        const loading = this.$loading({
          lock: true,
          text: '请稍后',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.3)'
        })
        queryThemeColor({ name: 'THEME_COLOR' })
          .then((res) => {
            switch (res.data.data.configValue) {
              case 'theme-one':
                defaultColor = '#eb523c'
              case 'theme-two':
                defaultColor = '#2f74eb'
              case 'theme-three':
                defaultColor = '#2DA7B5'
            }
            sessionStorage.setItem('THEME_COLOR', defaultColor)
            loading.close()
            resolve()
          })
          .catch((err) => {
            sessionStorage.setItem('THEME_COLOR', defaultColor)
            console.warn(err)
            loading.close()
            reject()
          })
      })
    },

    getListData(name) {
      return new Promise((resolve, reject) => {
        const loading = this.$loading({
          lock: true,
          text: '请稍后',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.3)'
        })
        /*  this.list = [
          {
            classifyName: '基础控件',
            pageInfo: [
              { 'id': '11-1', 'componentName': '分类导航', 'code': 'category', 'componentVariable': '[{"varName":"分类id","varCode":"classId","varValue":""},{"varName":"测试id","varCode":"testId","varValue":""}]', 'interfaceSetting': '[{"portName":"分类接口","portCode":"classPort"},{"portName":"测试 接口","portCode":"testPort"}]', 'correlationCondition': '[{"name":"改变","code":"change"}]', 'associationAction': '[{"name":"刷新","code":"refresh"}]' },

              {
                code: 'liveswiper',
                componentName: '直播轮播'
              },
              {
                code: 'bannerstyleone',
                componentName: 'banner样式一'
              },
              {
                code: 'vgridview',
                componentName: '网格样式'
              },
              {
                code: 'diamondArea',
                componentName: '金刚区'
              },
              {
                code: 'ninePalaceGrid',
                componentName: '九宫格'
              },
              {
                code: 'cglb',
                componentName: '闯关练兵'
              },
              {
                code: 'pictureContainer',
                componentName: '图片展示'
              }, {
                code: 'audioCourseList',
                componentName: '音频课程列表'
              }
            ]
          },
          {
            classifyName: '轮播组件',
            pageInfo: [
              {
                code: 'SwipeList',
                componentName: '列表轮播'
              }
            ]
          },
          {
            classifyName: '分类组件',
            pageInfo: [
              {
                code: 'ClassifyList',
                componentName: '列表分类'
              }
            ]
          },
          {
            classifyName: '人物信息控件',
            pageInfo: [
              {
                code: 'figurestyleone',
                componentName: '头像+姓名条（竖版）'
              },
              {
                code: 'horizontalName',
                componentName: '头像+姓名条（横版）'
              },
              {
                code: 'verticalCardOne',
                componentName: '人物竖版卡片(样式1)'
              },
              {
                code: 'figurestyletwo',
                componentName: '人物横版卡片(样式1)'
              },
              {
                code: 'horizontalCardTwo',
                componentName: '人物横版卡片(样式2)'
              }
            ]
          },
          {
            classifyName: '新闻组件',
            pageInfo: [
              {
                code: 'classifynewslistfixed',
                componentName: '带分类的新闻列表(固定数量)'
              }

            ]
          },
          {
            classifyName: '直播信息',
            pageInfo: [
              {
                code: 'liveListOne',
                componentName: '预约轮播'
              }

            ]
          },
          {
            classifyName: '每周重点',
            pageInfo: [
              {
                code: 'weekFocus',
                componentName: '每周重点'
              }

            ]
          }
        ]
        loading.close()
        resolve()
        return*/
        queryComponents({ componentName: name })
          .then((res) => {
            this.list = res.data.data
            loading.close()
            resolve()
          })
          .catch((err) => {
            console.warn(err)
            loading.close()
            reject()
          })
      })
    },
    getListItemInfo(code) {
      const obj = this.findPathByLeafId(code, this.list)
      return Object.prototype.toString.call(obj) === '[object Object]'
        ? obj
        : null
    },
    /**
		 * 根据id递归查找所在的对象
		 * @param data
		 * @returns {*}
		 */
    findPathByLeafId(leafId, nodes, path) {
      if (path === undefined) {
        path = {}
      }
      for (var i = 0; i < nodes.length; i++) {
        var tmpPath = path
        if (leafId === nodes[i].code) {
          tmpPath = nodes[i]
          return tmpPath
        }
        if (nodes[i].pageInfo) {
          var findResult = this.findPathByLeafId(
            leafId,
            nodes[i].pageInfo,
            tmpPath
          )
          if (findResult) {
            return findResult
          }
        }
      }
    },
    getDatas() {
      const { pageId } = this
      return new Promise((resolve, reject) => {
        const loading = this.$loading({
          lock: true,
          text: '请稍后',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.3)'
        })
        publish({ recordId: pageId }).then((res) => {
          loading.close()
          const obj = res.data.data.config
            ? JSON.parse(res.data.data.config)
            : null
          this.ctId = res.data.data.id
          if (obj) {
            const {
              components,
              relation,
              pageconfig,
              headerconfig,
              footerconfig,
              pageVar
            } = obj
            this.setValue({
              components,
              pageVar,
              relation,
              pageconfig,
              headerconfig,
              footerconfig
            })
          }
        })
      })
    },
    getData() {
      const { pageId } = this
      return new Promise((resolve, reject) => {
        const loading = this.$loading({
          lock: true,
          text: '请稍后',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.3)'
        })
        query({ id: pageId }).then((res) => {
          loading.close()
          const obj = res.data.data.config
            ? JSON.parse(res.data.data.config)
            : null
          if (obj) {
            const {
              components,
              relation,
              pageconfig,
              headerconfig,
              footerconfig,
              pageVar
            } = obj
            this.setValue({
              components,
              pageVar,
              relation,
              pageconfig,
              headerconfig,
              footerconfig
            })
          }
        })
      })
    },
    px2rem(px) {
      return (px && (px / 75) * 1 + 'rem') || ''
    },
    toggle(data) {
      const { from, to, fromType, toType, position } = data
      if (fromType === toType && fromType === 'layout') {
        let fromIndex = null
        let toIndex = null
        this.comps.forEach((a, i) => {
          if (a.id === from) {
            fromIndex = i
          }
          if (a.id === to) {
            toIndex = i
          }
        })
        if (position === 'next') {
          toIndex = toIndex + 1
          if (toIndex > this.comps.length) {
            toIndex = this.comps.length - 1
          }
          this.move(this.comps, fromIndex, toIndex)
        } else {
          this.move(this.comps, fromIndex, toIndex)
        }
      } else if (fromType === toType && fromType === 'wrapper') {
        let fromIndex = null
        let toIndex = null
        let fromLayoutId = null
        let toLayoutId = null
        this.comps.forEach((component) => {
          (component.components || []).forEach((a, i) => {
            if (a.id === from) {
              fromLayoutId = component.id
              fromIndex = i
            }
            if (a.id === to) {
              toLayoutId = component.id
              toIndex = i
            }
          })
        })
        if (fromLayoutId === toLayoutId) {
          const t = this.comps.find((a) => a.id === fromLayoutId)
          if (position === 'before') {
            this.move(t.components, fromIndex, toIndex)
          } else {
            toIndex = toIndex + 1
            if (toIndex > t.components.length) {
              toIndex = t.components.length - 1
            }
            this.move(t.components, fromIndex, toIndex)
          }
        } else {
          const t = this.comps.find((a) => a.id === fromLayoutId)
          const tIndex = t.components.findIndex((a) => a.id === from)
          const q = t.components.splice(tIndex, 1)[0]
          const f = this.comps.find((a) => a.id === toLayoutId)
          let fIndex = f.components.findIndex((a) => a.id === to)
          if (position === 'before') {
            fIndex = fIndex - 1
            if (fIndex < 0) {
              fIndex = 0
            }
            f.components.splice(fIndex, 0, q)
          } else {
            fIndex = fIndex + 1
            if (fIndex > f.components.length) {
              fIndex = f.components.length - 1
            }
            f.components.splice(fIndex, 0, q)
          }
        }
      } else if (fromType === 'wrapper' && toType === 'layout') {
        let toLayout = null
        let fromLayout = null
        let fromIndex = null
        let fromObject = null
        this.comps.forEach((a) => {
          if (a.id === to) {
            toLayout = a
          }
          a.components.forEach((b, i) => {
            if (b.id === from) {
              fromLayout = a
              fromIndex = i
              fromObject = b
            }
          })
        })
        toLayout.components.push(fromObject)
        fromLayout.components.splice(fromIndex, 1)
      } else if (fromType === 'adder' && toType === 'layout') {
        const { adderName } = data
        const info = FieldMap.getField(adderName)
        if (info) {
          const t = this.comps.find((a) => a.id === to)
          if (t.components.length > 0) {
            t.components.splice(0, 1, {
              type: 'wrapper',
              id: randomStringForId(8),
              option: {
                name: info.name,
                target: info.target,
                option: { ...info.parameter }
              }
            })
          } else {
            t.components.push({
              type: 'wrapper',
              id: randomStringForId(8),
              option: {
                name: info.name,
                target: info.target,
                option: { ...info.parameter }
              }
            })
          }
        }
      } else if (fromType === 'adder' && toType === 'wrapper') {
        const { adderName } = data
        const info = FieldMap.getField(adderName)
        if (info) {
          let toIndex = null
          let toLayoutId = null
          this.comps.forEach((component) => {
            (component.components || []).forEach((a, i) => {
              if (a.id === to) {
                toLayoutId = component.id
                toIndex = i
              }
            })
          })
          const t = this.comps.find((a) => a.id === toLayoutId)

          if (position === 'next') {
            toIndex = toIndex + 1
            if (toIndex > t.components.length) {
              toIndex = t.components.length - 1
            }
          }
          t.components.splice(toIndex, 0, {
            type: 'wrapper',
            id: randomStringForId(8),
            option: {
              name: info.name,
              target: info.target,
              option: { ...info.parameter }
            }
          })
        }
      }
    },

    move(input, from, to) {
      if (from !== to) {
        let numberOfDeletedElm = 1
        const elm = input.splice(from, numberOfDeletedElm)[0]
        numberOfDeletedElm = 0
        input.splice(to, numberOfDeletedElm, elm)
        return input
      }
    },

    dragStart(data) {
      this.dragState = data
    },

    drop(e) {
      const { type } = this.dragState
      if (type === 'adder') {
        this.enter = false
        this.dispatch_event('add-wapper', {
          adderName: e.dataTransfer.getData('name')
        })
      }
    },

    dragOver() {
      const { type } = this.dragState
      if (type === 'adder') {
        this.enter = true
      }
    },

    dragLeave() {
      this.enter = false
    },

    addLayout() {
      this.comps.push({
        type: 'layout',
        id: randomStringForId(8),
        components: []
      })
    },

    removeLayout(id) {
      const t = this.comps.findIndex((a) => a.id === id)
      if (t !== -1) {
        this.comps.splice(t, 1)
      }
    },

    addWapper(data) {
      const { adderName } = data
      const info = FieldMap.getField(adderName)
      if (info) {
        this.comps.push({
          type: 'layout',
          id: randomStringForId(8),
          components: [
            {
              type: 'wrapper',
              id: randomStringForId(8),
              option: {
                name: info.name,
                target: info.target,
                option: { ...info.parameter }
              }
            }
          ]
        })
      }
    },

    removeWapper(id) {
      let layoutId = null
      let warpperId = null
      this.comps.some((a, index) => {
        const t = a.components.findIndex((b) => b.id === id)
        if (t !== -1) {
          warpperId = t
          layoutId = index
          return true
        } else {
          return false
        }
      })
      if (layoutId !== null && warpperId !== null) {
        this.comps[layoutId].components.splice(warpperId, 1)
      }
    },

    focusWapper(data) {
      const { id, name } = data
      let r = null
      this.focusId = id
      this.focusName = name
      this.comps.some((a) => {
        const t = a.components.find((b) => b.id === id)
        if (t) {
          r = t
          return true
        } else {
          return false
        }
      })
      const t = FieldMap.getFieldOptionForm(name, r.option.option, null)
      const beforeComponents = []
      const next = true
      this.comps.forEach((a) => {
        a.components.forEach((b) => {
          const info = FieldMap.getField(b.option.name)
          const { relate = false } = info.parameter
          if (b.id !== this.focusId && relate) {
            const operator = FieldMap.getFieldOperators(b.option.name)
            if (operator.length > 0) {
              beforeComponents.push({
                field: {
                  typeName: b.option.name,
                  type: info.target,
                  label: b.option.option.label,
                  id: b.id,
                  option: { ...b.option.option, label: '' },
                  valueType: info.valueType
                },
                operator
              })
            }
          }
        })
      })
      if (beforeComponents.length > 0) {
        t.push({
          title: '关联设置',
          fields: [
            {
              type: Extend,
              option: {
                name: 'relate',
                initalize: false,
                label: '组件关联设置',
                fields: [
                  {
                    type: VRelate,
                    option: { name: 'relate', fields: beforeComponents }
                  }
                ],
                value: this.relation[id] || null
              }
            }
          ]
        })
        /* t.push({
          title: '关联设置',
          fields: [
            {
              type: Extend,
              option: {
                name: 'relate',
                initalize: false,
                label: '前置组件关联设置',
                fields: [
                  {
                    type: VRelate,
                    option: { name: 'relate', fields: beforeComponents }
                  }
                ],
                value: this.relation[id] || null
              }
            }
          ]
        })*/
      }
      // 获取接口数据
      this.setPort(this.focusId, name, t)
      this.focusForm = t
      this.getCompVar(name)
      this.getLabelFun()
      this.active = 'widget'
    },
    // 设置接口
    setPort(id, name, t) {
      // 获取接口数据
      const compObj = this.getCompObj(id)
      const portArr = this.getPortList(name) // 组件定义的接口模板
      const dynamicData = []
      if (
        compObj !== null &&
				compObj?.option?.option?.dynamicData?.length > 0
      ) {
        const myData = compObj.option.option.dynamicData
        portArr.forEach((item) => {
          const obj = myData.find((ite) => {
            return item.code === ite.configCode
          })
          if (obj === undefined || obj.link === '') {
            dynamicData.push({
              configName: item.name,
              configCode: item.code,
              choosePort: '',
              link: '',
              name: '',
              params: []
            })
          } else {
            const cur = this.portList.find((ite) => {
              return (ite.id = obj.choosePort)
            })
            if (cur !== undefined) {
              dynamicData.push(obj)
            } else {
              dynamicData.push({
                configName: item.name,
                configCode: item.code,
                choosePort: '',
                link: '',
                name: '',
                params: []
              })
            }
          }
        })
      } else {
        for (let i = 0; i < portArr.length; i++) {
          dynamicData.push({
            configName: portArr[i].name,
            configCode: portArr[i].code,
            choosePort: '',
            link: '',
            name: '',
            params: []
          })
        }
      }
      t.forEach((a) => {
        a.fields.forEach((b) => {
          if (b.option.name === 'dynamicData') {
            b.option.value = dynamicData
          } else if (b.option.name === 'compName') {
            b.option.value = name
          } else if (
            b.option.name === 'fixedData' &&
						b.option.portName !== undefined &&
						b.option.value
          ) {
            b.option.value = b.option.value[b.option.portName].data
          }
        })
      })
    },
    // 获取标签分类
    getLabelFun() {
      this.labelClass = []
      return new Promise((resolve, reject) => {
        getLabel({ classifyType: 'FLLX_BQ', status: 'ZT01', id: 'SAAS' }).then(
          (res) => {
            this.labelClass =
							res.data.data && res.data.data.length > 0 ? res.data.data : []
          }
        )
      })
    },
    // 获取登记的接口
    getPortApi() {
      this.portList = []
      return new Promise((resolve, reject) => {
        getPort({ comId: this.getListItemInfo(this.focusName).id })
          .then((res) => {
            const list =
							res.data.data && res.data.data.length > 0 ? res.data.data : []
            list.forEach((item) => {
              this.portList.push({
                value: item.id,
                name: item.pageName,
                ...item
              })
            })
            resolve()
          })
          .catch((e) => {
            resolve()
          })
      })
    },
    getPortListFun(id) {
      this.portList = []
      return new Promise((resolve, reject) => {
        getPort({ comId: id })
          .then((res) => {
            const list =
							res.data.data && res.data.data.length > 0 ? res.data.data : []
            list.forEach((item) => {
              this.portList.push({
                value: item.id,
                name: item.pageName,
                ...item
              })
            })
            resolve()
          })
          .catch((e) => {
            resolve()
          })
      })
    },
    // 获取接口数组
    getPortList(name) {
      const info = this.getListItemInfo(name)
      let arr = []
      try {
        arr = JSON.parse(info.interfaceSetting)
      } catch (e) {
        arr = []
      }
      return arr
    },
    // 获取组件变量模板
    getCompVar(name) {
      const info = this.getListItemInfo(name)
      let initVar = []
      try {
        initVar = JSON.parse(info.componentVariable)
      } catch (e) {
        initVar = []
      }
      // 如果组件有初始化的变量值，直接取
      const { compIndex, childIndex } = this.getCompIndex(this.focusId)
      if (this.comps[compIndex].components[childIndex]?.compVar?.length > 0) {
        const oldVar =
					this.comps[compIndex].components[childIndex].compVar || []
        // 取sass端的变量，重新赋值
        const newVar = []
        initVar.forEach((item) => {
          const obj = oldVar.find((ite) => {
            return ite.code === item.code
          })
          let value = ''
          if (obj !== undefined && obj['value'] !== undefined) {
            value = obj.value || ''
          }
          newVar.push({
            name: item['name'],
            code: item['code'],
            value: value
          })
        })
        this.compVar = newVar
      } else {
        // 拿到组件的初始变量
        this.compVar = initVar
      }
    },
    // 为对应组件设置值
    setCompVar(data) {
      const { compIndex, childIndex } = this.getCompIndex(this.focusId)
      if (compIndex === -1) {
        return false
      }
      const obj = deepClone(this.comps[compIndex])
      obj.components[childIndex]['compVar'] = data || []
      this.$set(this.comps, compIndex, obj)
    },

    // 获取当前组件的下标
    getCompIndex(id) {
      let compIndex = -1
      let childIndex = -1
      try {
        this.comps.forEach((item, index) => {
          if (childIndex === -1) {
            childIndex = item.components.findIndex((ite) => {
              return ite.id === id
            })
            compIndex = index
          } else {
            throw new Error('return')
          }
        })
      } catch (e) {
        console.log(e)
      }
      return { compIndex, childIndex }
    },
    // 获取当前点击的组件
    getCompObj(id) {
      let compIndex = -1
      let childIndex = -1
      try {
        this.comps.forEach((item, index) => {
          if (childIndex === -1) {
            childIndex = item.components.findIndex((ite) => {
              return ite.id === id
            })
            compIndex = index
          } else {
            throw new Error('return')
          }
        })
      } catch (e) {
        console.log(e)
      }
      return compIndex === -1
        ? null
        : this.comps[compIndex].components[childIndex]
    },

    focusHeader() {
      this.active = 'widget'
      this.focusId = 'header'
      const t = FieldMap.getFieldOptionForm('header', this.headerconfig, null)
      this.focusForm = t
    },
    focusFooter() {
      this.active = 'widget'
      this.focusId = 'footer'
      const t = FieldMap.getFieldOptionForm('footer', this.footerconfig, null)
      const obj = this.getListItemInfo('Footer')
      this.setPort(obj.id, 'Footer', t)
      this.focusForm = t
    },

    getValue() {
      const f = []
      const relation = {}
      let flag = true
      this.comps.forEach(({ components }) => {
        const t = []
        components.forEach(({ option, id, compVar }) => {
          let { name, option: _option } = option
          if (name === 'empty') {
            flag = false
            this.$message.error('存在空组件，请替换或删除！')
            return
          }
          const r = FieldMap.getField(name)
          const valueType = r ? r.valueType || '' : ''
          if (!_option.name) {
            _option = {
              ..._option,
              name: `A${randomStringForId(8)}`
            }
          }
          t.push({
            ..._option,
            id,
            compVar: compVar !== undefined ? compVar : [],
            type: name,
            valueType
          })
          if (this.relation[id]) {
            relation[id] = this.relation[id]
          }
        })
        f.push(t)
      })
      return {
        components: f,
        relation,
        pageVar: this.pageVar,
        pageconfig: this.pageconfig,
        headerconfig: this.headerconfig,
        footerconfig: this.footerconfig,
        flag
      }
    },

    setValue({
      components = [],
      pageVar = [],
      relation = {},
      pageconfig = {},
      headerconfig = {},
      footerconfig = {}
    } = {}) {
      // components.push([{ type: 'emp', id: '1233-11' }])
      let r = components.map((items) => {
        const components = items.map((option) => {
          let ops = { ...option }
          const field = FieldMap.getField(option.type)
          const { target, name } = field
          if (name === 'empty') {
            // 没有找到对应组件
            return {
              id: option.id,
              type: 'wrapper',
              compVar: [],
              option: {
                name: 'empty',
                target,
                option: []
              }
            }
          } else {
            if (field.defaultOption) {
              ops = Object.assign({}, ops, field.defaultOption(field))
            }
            delete ops.type
            return {
              id: option.id,
              type: 'wrapper',
              compVar: option.compVar !== undefined ? option.compVar : [],
              option: {
                name: option.type,
                target,
                option: ops
              }
            }
          }
        })
        return {
          type: 'layout',
          components,
          id: randomStringForId(8)
        }
      })
      if (r.length === 0) {
        r = [{ type: 'layout', id: '1', components: [] }]
      }
      this.setBaseInfo({
        components: r,
        relation,
        pageconfig,
        headerconfig,
        footerconfig,
        pageVar
      })
    },

    setBaseInfo(info) {
      this.$set(this, 'comps', info.components || [])
      this.$set(this, 'relation', info.relation || [])
      this.$set(this, 'pageconfig', info.pageconfig || [])
      this.$set(this, 'headerconfig', info.headerconfig || [])
      this.$set(this, 'footerconfig', info.footerconfig || [])
      this.$set(this, 'pageVar', info.pageVar || [])
    },

    clear() {
      this.$set(this, 'pageconfig', {})
      this.$set(this, 'headerconfig', {})
      this.$set(this, 'footerconfig', {})
      this.$set(this, 'pageVar', [])
      this.$set(this, 'compVar', [])
      this.broadcast_event('clear-header', '')
      this.comps = []
      this.focusForm = []
      this.focusId = null
      this.focusName = ''
    },

    save(isBack) {
      const obj = this.getValue()
      const { flag } = obj
      if (!flag) {
        return false
      }
      const loading = this.$loading({
        lock: true,
        text: '请稍后',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.3)'
      })
      if (this.ctType !== '') {
        const pageId = this.ctId
        return new Promise((resolve, reject) => {
          save({
            id: pageId,
            insertRecode: 'insert',
            config: JSON.stringify(obj)
          }).then((res) => {
            loading.close()
            this.$message({
              title: '成功',
              message: '保存成功',
              type: 'success',
              duration: 2000
            })
            if (isBack) {
              this.handleBack()
            }
          })
        })
      } else {
        const { pageId } = this
        return new Promise((resolve, reject) => {
          save({
            id: pageId,
            insertRecode: 'insert',
            config: JSON.stringify(obj)
          }).then((res) => {
            loading.close()
            this.$message({
              title: '成功',
              message: '保存成功',
              type: 'success',
              duration: 2000
            })
            if (isBack) {
              this.handleBack()
            }
          })
        })
      }
    },

    /**
		 * 返回按钮
		 */
    handleBack() {
      this.$router.back()
    },
    async view() {
      this.varList = this.pageVar
      if (this.varList.length) {
        this.varList.forEach((item) => {
          this.$set(this.varForm, item.code, item.value)
        })
        this.visible = true
      } else {
        this.preview()
      }
    },
    handleVarSubmit() {
      this.visible = false
      this.preview()
      /*  if (Object.values(this.varForm).some(item => {
        return item
      })) {
        this.visible = false
        this.preview()
      } else {
        this.$message({
          message: '初始信息不能为空',
          type: 'warning'
        })
      }*/
    },
    async preview() {
      const { default: DialogView } = await import('./view')
      this.$modal.show(
        DialogView,
        {
          title: '',
          inner: this.getValue(),
          varInfo: this.varForm,
          fn: this.handleComit,
          isInitData: true
        },
        {
          width: 375,
          height: 'auto',
          clickToClose: true,
          draggable: true
        }
      )
    },

    widgetformchange(data) {
      const { focusId, comps } = this
      if (focusId === 'header') {
        this.$set(this, 'headerconfig', data)
      } else if (focusId === 'footer') {
        this.$set(this, 'footerconfig', data)
      } else {
        const tx = {}
        const id = focusId
        Reflect.ownKeys(data).forEach((a) => {
          if (a !== 'relate') {
            tx[a] = data[a]
          }
        })
        const t = deepClone(comps)
        t.forEach((a) => {
          const t = a.components.find((b) => b.id === focusId)
          if (t) {
            t.option.option = Object.assign(t.option.option || {}, tx)
          }
        })

        this.relation[id] = data.relate || []
        this.$set(this, 'comps', t)
      }
    },
    pageformchange(data) {
      this.$set(this, 'pageconfig', data)
    }
  }
}
</script>
<style lang="scss">
.form-view .content {
	padding: 0 !important;
}
.header {
	display: none !important;
}
</style>
<style lang="scss" scoped>
@import '@/styles/var.scss';
@import '@/styles/utility/shadow.scss';
@import '@/styles/utility/position.scss';
@import '@/styles/utility/center.scss';

.pagemaker {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	box-sizing: border-box;

	&-list {
		width: 340px;
		@include absolute(0, none, 0, 0);
		@include boxShadow(3);
		z-index: 99;

		&-header {
			line-height: 40px;
			padding: 0 15px 0 15px;
			font-size: 13px;
			cursor: default;
		}

		&-body {
			@include absolute(40px, 0, 0, 0);
			//overflow: auto;
			border-top: 1px solid $f6;
		}
	}

	&-editor {
		height: 100%;
		@include absolute(0, 445px, 0, 345px);
		z-index: 999;
		box-sizing: border-box;
		background: #fff;
		overflow-x: hidden;

		.pagemaker-editor-header {
			height: 40px;
			padding: 0 15px 0 15px;
			font-size: 13px;
			display: flex;
			align-items: center;
			justify-content: space-between;
			position: relative;
			z-index: 9;

			&-action {
				display: flex;
				align-items: center;
				height: 100%;
				.item {
					height: 100%;
					margin-left: 15px;
					font-size: 12px;
					display: flex;
					align-items: center;
					cursor: pointer;

					.icon {
						margin-right: 5px;
					}
					.txt {
						cursor: pointer;
					}
					&:hover {
						color: $a1;
					}
				}
			}
		}

		&-body {
			@include absolute(40px, 0, 0, 0);
			border-top: 1px solid $f6;
			overflow: auto;
			background: $f8;
			padding: 30px 0 100px 0px;
			transition: all ease 0.3s;

			&-banner {
				width: 375px;
				height: 64px;
				margin: 0 auto;
				background-color: #fff;
				border-radius: 4px 4px 0 0;
				box-shadow: #ebedf0 0 4px 12px;

				> div {
					border-radius: 4px 4px 0 0;
					background: url('../images/pageditor/header.png') no-repeat 50% /
						cover;
					font-size: 14px;
					display: block;
					height: 64px;
					line-height: 82px;
					text-overflow: ellipsis;
					white-space: nowrap;
					overflow: hidden;
					cursor: pointer;
					margin: 0 auto;
				}
			}

			&-info {
				margin-left: 30px;
				margin-right: 30px;
				background: $f9;
				border-radius: 5px 5px 0 0;
				@include boxShadow(1);
				position: relative;
				padding: 40px 60px;

				&-icon {
					width: 35px;
					height: 35px;
					@include center();
					background: $a1;
					color: $f9;
					border-radius: 50%;
					@include absolute(none, none, 100%, 20px);
					transform: translateY(50%);
					border: 2px solid $f5;
					font-size: 18px;
				}
			}

			&-footer {
				width: 375px;
				margin: 0 auto;
				margin-top: 24px;
				background-color: #fff;
				height: 60px;
				display: flex;
				align-items: center;
				justify-content: center;
				border: 1px dotted $f6;
				cursor: pointer;
				@include boxShadow(1);

				&:hover {
					border-color: $a1;
					color: $a1;
					font-size: 20px;
				}

				&.enter {
					border-color: $a1;
					color: $a1;
					font-size: 20px;
				}
			}
		}
	}

	&-form {
		width: 440px;
		@include absolute(0, 0, 0, none);
		@include boxShadow(3);
		z-index: 1000;

		/deep/ .el-tabs {
			.el-tabs__header {
				margin: 0;
			}

			.el-tabs__nav-wrap::after {
				height: 0;
			}

			.el-tabs__item {
				width: 100px;
				text-align: center;
				padding: 0;
			}
		}

		&-header {
			line-height: 40px;
			padding: 0 15px 0 15px;
			font-size: 13px;
			cursor: default;
		}

		&-body {
			@include absolute(40px, 0, 0, 0);
			overflow: auto;
			border-top: 1px solid $f6;
		}
	}
}
</style>
<style lang="scss">
.vm--container {
	z-index: 1001;
}
</style>
